package net.qhzw.vip.qiyu.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.config.WxPayConfiguration;
import net.qhzw.vip.qiyu.constant.CacheConstants;
import net.qhzw.vip.qiyu.dto.ContractDto;
import net.qhzw.vip.qiyu.entity.DtsCarRental;
import net.qhzw.vip.qiyu.entity.DtsCarRentalRefund;
import net.qhzw.vip.qiyu.handler.ApiException;
import net.qhzw.vip.qiyu.model.AdminCarRentalAppForm;
import net.qhzw.vip.qiyu.model.CarRentalCostsForm;
import net.qhzw.vip.qiyu.model.CarRentalCostsVo;
import net.qhzw.vip.qiyu.model.UserCarRental;
import net.qhzw.vip.qiyu.result.JsonResult;
import net.qhzw.vip.qiyu.service.DtsCarRentalRefundService;
import net.qhzw.vip.qiyu.service.DtsCarRentalService;
import net.qhzw.vip.qiyu.service.DtsUserService;
import net.qhzw.vip.qiyu.util.MyDateUtils;
import net.qhzw.vip.qiyu.util.RedisUtils;
import net.qhzw.vip.qiyu.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

@RestController
@RequestMapping("dts/carRental")
@Api(tags = "租车申请管理")
@Slf4j
public class DtsCarRentalController {

    @Autowired
    private DtsCarRentalService dtsCarRentalService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private DtsCarRentalRefundService carRentalRefundService;

    @Autowired
    private DtsUserService dtsUserService;

    @Autowired
    private RedisTemplate redisTemplate;


    @ApiOperation(value = "根据当前登录用户获取租车信息")
    @GetMapping("getCarRentalByUser")
    public JsonResult<UserCarRental> getCarRentalByUser() {
        UserCarRental userCarRental = dtsCarRentalService.getCarRentalByUser();
        return JsonResult.ok(userCarRental);
    }

    @ApiOperation(value = "用户提交租车申请")
    @PostMapping("userSubmitCarRentalApp")
    public JsonResult userSubmitCarRentalApp(@RequestBody Map<String, String> param) {
        Long communityId = Long.valueOf(param.get("communityId")); //站点ID
        boolean isOK = dtsCarRentalService.userSubmitCarRentalApp(communityId);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }

    @ApiOperation(value = "分页查询租车申请列表")
    @GetMapping
    public JsonResult findByPage(Page<DtsCarRental> page, String keywords) {
        Map<String, Object> result = dtsCarRentalService.findByPage(page, keywords);
        return JsonResult.ok(result);
    }

    @ApiOperation(value = "站点管理员提交租车申请")
    @PostMapping("adminCarRentalApp")
    public JsonResult adminCarRentalApp(@RequestBody AdminCarRentalAppForm form) {
        boolean isOK = dtsCarRentalService.adminCarRentalApp(form);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }

    @ApiOperation(value = "查询用户合同期内的租车申请次数")
    @GetMapping("count")
    public JsonResult<Integer> getCount() {
        Long userId = SecurityUtils.getUserId();
        int status = dtsUserService.getUserStatus(userId);
        if (1 != status) {
            throw new ApiException("您的账号已限制,请联系站点管理员!");
        }
        int count = dtsCarRentalService
                .count(new LambdaQueryWrapper<DtsCarRental>()
                        .eq(DtsCarRental::getUserId, SecurityUtils.getUserId())
                        .ne(DtsCarRental::getStatus, 4));
        return JsonResult.ok(count);
    }

    @ApiOperation(value = "分页查询用户租车申请列表")
    @GetMapping("list")
    public JsonResult<Page<DtsCarRental>> getList(Page<DtsCarRental> page, Byte status) {
        Page<DtsCarRental> dtsCarRentalPage = dtsCarRentalService.page(page, new LambdaQueryWrapper<DtsCarRental>()
                .eq(DtsCarRental::getUserId, SecurityUtils.getUserId())
                .eq(status != null, DtsCarRental::getStatus, status));
        return JsonResult.ok(dtsCarRentalPage);
    }

    @ApiOperation(value = "结算租车费用明细")
    @PostMapping("carRentalCosts")
    public JsonResult<CarRentalCostsVo> carRentalCosts(@RequestBody CarRentalCostsForm form) {
        CarRentalCostsVo result = dtsCarRentalService.carRentalCosts(form);
        return JsonResult.ok(result);
    }


    @ApiOperation(value = "租车处理支付回调")
    @PostMapping("/pay/notify")
    public JsonResult payNotify(@RequestBody String xmlData) {
        //log.info("【租车支付回调】： {}", xmlData);
        WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
        String SubMchId = rs.getSubMchId();
        String appId = rs.getAppid();
        String payNo = rs.getOutTradeNo();
        String bizPayNo = rs.getTransactionId();
        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setSubMchId(SubMchId);
        WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
        String orderCache = (String) redisTemplate.boundListOps(CacheConstants.CAR_RENTA_ORDER_CACHE + ":" + payNo).rightPop();
        try {
            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            if (!StringUtils.isEmpty(orderCache)) {
                CarRentalCostsVo rentalCostsVo = JSONObject.parseObject(orderCache, CarRentalCostsVo.class);
                DtsCarRental carRental = dtsCarRentalService.getById(rentalCostsVo.getId());
                if (carRental != null && 1 == carRental.getIsPayed()) {
                    return JsonResult.ok();
                }
                DtsCarRental dtsCarRental = new DtsCarRental();
                dtsCarRental.setId(rentalCostsVo.getId());
                dtsCarRental.setIsPayed((byte) 1);
                dtsCarRental.setPayTime(new Date());
                dtsCarRental.setOrderNumber(payNo);
                dtsCarRental.setApprovalTime(new Date());
                dtsCarRentalService.updateById(dtsCarRental);

                //租车支付详情
                DtsCarRentalRefund carRentalRefund = new DtsCarRentalRefund();
                carRentalRefund.setId(IdWorker.getId());
                carRentalRefund.setOrderId(rentalCostsVo.getId());
                carRentalRefund.setFlowTradeNo(payNo);
                carRentalRefund.setOrderNumber(payNo);
                carRentalRefund.setOrderAmount(rentalCostsVo.getTotalRent().doubleValue());
                carRentalRefund.setOutRefundNo(bizPayNo);
                carRentalRefund.setAppId(appId);
                carRentalRefund.setPayTypeName(MyDateUtils.getCurDt() + "租车费用");
                carRentalRefund.setUserId(rentalCostsVo.getUserId());
                carRentalRefundService.save(carRentalRefund);

            }


            return JsonResult.ok(notifyResult);
        } catch (WxPayException e) {
            log.error("处理支付回调err {}", JSON.toJSONString(e));
            return JsonResult.fail(e.getReturnMsg() + "" + e.getCustomErrorMsg() + "" + e.getErrCodeDes());
        }

    }

    @ApiOperation(value = "申请租车(生成合同)")
    @PostMapping("createContract")
    public JsonResult createContract(@RequestBody CarRentalCostsForm form, HttpServletRequest request) {
        log.info("申请租车 :{}", JSON.toJSONString(form));
        boolean isOK = dtsCarRentalService.createContract(form, request);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }

    @ApiOperation(value = "根据租车id获取合同")
    @GetMapping("getContract/{id}")
    public JsonResult createContract(@PathVariable Long id) throws InterruptedException {
        Thread.sleep(2000);
        DtsCarRental dtsCarRental = dtsCarRentalService.getById(id);
        return JsonResult.ok(dtsCarRental.getContent());
    }

    @ApiOperation(value = "用户签名")
    @PostMapping("usrSignature")
    public JsonResult usrSignature(@RequestBody Map<String, String> param, HttpServletRequest request) {
        Long id = Long.valueOf(param.get("id"));
        String sign = param.get("sign");
        boolean isOK = dtsCarRentalService.usrSignature(id, sign, request);
        if (isOK) {
            return JsonResult.ok();
        }
        return JsonResult.fail();
    }


    @ApiOperation(value = "查询租车合同公司")
    @GetMapping("contract")
    public JsonResult contract() {
        Long userId = SecurityUtils.getUserId();
        ContractDto contractDto = dtsCarRentalService.findCarRentalContract(userId);
        return JsonResult.ok(contractDto);
    }





    /*@ApiOperation(value = "租车处理支付回调")
    @PostMapping("/pay/notify")
    public JsonResult payNotify(@RequestBody String xmlData) {
        log.info("【租车支付回调】： {}", xmlData);
        WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
        String payNo = rs.getOutTradeNo();
        String bizPayNo = rs.getTransactionId();
        //String orderCache = redisUtils.getCacheObject(CacheConstants.CAR_RENTA_ORDER_CACHE + ":" + payNo);
        String orderCache = (String) redisTemplate.boundListOps(CacheConstants.CAR_RENTA_ORDER_CACHE + ":" + payNo).rightPop();
        if (!StringUtils.isEmpty(orderCache)) {
            CarRentalCostsVo rentalCostsVo = JSONObject.parseObject(orderCache, CarRentalCostsVo.class);
            DtsCarRental carRental = dtsCarRentalService.getById(rentalCostsVo.getId());
            if (carRental != null && 1 == carRental.getIsPayed()) {
                return JsonResult.ok();
            }
            DtsCarRental dtsCarRental = new DtsCarRental();
            dtsCarRental.setId(rentalCostsVo.getId());
            dtsCarRental.setIsPayed((byte) 1);
            dtsCarRental.setPayTime(new Date());
            dtsCarRental.setOrderNumber(payNo);
            dtsCarRental.setApprovalTime(new Date());
            dtsCarRentalService.updateById(dtsCarRental);
            //租车支付详情
            DtsCarRentalRefund carRentalRefund = new DtsCarRentalRefund();
            carRentalRefund.setId(IdWorker.getId());
            carRentalRefund.setOrderId(rentalCostsVo.getId());
            carRentalRefund.setFlowTradeNo(payNo);
            carRentalRefund.setOrderNumber(payNo);
            carRentalRefund.setOrderAmount(rentalCostsVo.getTotalRent().doubleValue());
            carRentalRefund.setOutRefundNo(bizPayNo);
            carRentalRefund.setPayTypeName(MyDateUtils.getCurDt() + "租车费用");
            carRentalRefund.setUserId(rentalCostsVo.getUserId());
            carRentalRefundService.save(carRentalRefund);
        }
        return JsonResult.ok();
    }*/

}
